import React, {
  createContext,
  useState,
  useEffect,
  useRef,
  useContext,
  useMemo,
} from "react";

const Context = createContext(null);

export function AliveScope(props: any) {
  const [state, setState] = useState({});
  const ref: any = useMemo(() => {
    return {};
  }, []);
  const keep: any = useMemo(() => {
    return (id: any, children: any) =>
      new Promise((resolve) => {
        setState({
          [id]: { id, children },
        });
        setTimeout(() => {
          //需要等待setState渲染完拿到实例返回给子组件。
          resolve(ref[id]);
        });
      });
  }, [ref]);
  return (
    <Context.Provider value={keep}>
      {props.children}
      {Object.values(state).map(({ id, children }: any) => (
        <div
          key={id}
          ref={(node) => {
            ref[id] = node;
          }}
        >
          {children}
        </div>
      ))}
    </Context.Provider>
  );
}

function KeepAlive(props: any) {
  const keep: any = useContext(Context);
  useEffect(() => {
    const init = async ({ id, children }: any) => {
      const realContent = await keep(id, children);
      if (ref.current) {
        ref.current.appendChild(realContent);
      }
    };
    init(props);
  }, [props, keep]);
  const ref: any = useRef(null);
  return <div ref={ref} />;
}

export default KeepAlive;
